import { cloneDeep, set as setValue } from 'lodash-es'
import { reactive } from 'vue'

/**
 * 表单数据hook
 * @param initValue 初始值
 */
export function useFormData(init) {
  let initValue = init == null ? {} : cloneDeep(init)
  /** 表单数据 */
  const form = reactive(init == null ? {} : cloneDeep(init))

  /** 重置为初始值 */
  function resetFields(field, excludes) {
    const keys = Object.keys(form)
    if (typeof field === 'string' && field) {
      if (keys.includes(field)) {
        form[field] = cloneDeep(initValue[field])
      }
      return
    }
    const initValueClone = cloneDeep(initValue)
    keys.forEach((key) => {
      if (!excludes || !excludes.includes(key)) {
        form[key] = initValueClone[key]
      }
    })
  }

  /** 赋值不改变字段 */
  function assignFields(data, excludes) {
    if (excludes === true) {
      initValue = data == null ? {} : cloneDeep(data)
      const initValueKeys = Object.keys(initValue)
      Object.keys(form).forEach((key) => {
        form[key] = void 0
        if (!initValueKeys.includes(key)) {
          delete form[key]
        }
      })
      if (data != null) {
        Object.assign(form, cloneDeep(data))
      }
      return
    }
    Object.keys(form).forEach((key) => {
      if (!excludes || !excludes.includes(key)) {
        form[key] = data?.[key]
      }
    })
  }

  /** 赋值某字段 */
  function setFieldValue(field, value) {
    setValue(form, field, value)
  }

  const result = [form, resetFields, assignFields, setFieldValue]
  // 支持对象解构以兼容旧版
  Object.assign(result, {
    form,
    resetFields,
    assignFields,
  })
  return result
}
